package com.totoro.tyrank.utils;


import com.totoro.tyrank.TyRank;
import com.totoro.tyrank.constants.StaticSystemVarConst;
import com.totoro.tyrank.data.PlayerData;
import com.totoro.tyrank.data.PlayerSortData;
import org.bukkit.entity.Player;

import java.time.LocalDateTime;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * @author TOTORO
 * @date 2024/8/29 14:39
 */
public class ListUtil {


    /**
     * @author totoro
     * @description 将字符串格式为"攻击力: + 100", "攻击力: 100", "血量: +100" 这样格式的集合进行合并返回新集合
     * @date  18:57
     * @param [stats]
     * @return java.util.List<java.lang.String>
     **/
    public static List<String> mergeStats(List<String> stats) {
        // 存储每个属性的总和
        Map<String, Integer> valueMap = new HashMap<>();
        // 存储每个属性首次出现的符号格式
        Map<String, String> symbolMap = new HashMap<>();
        // 正则表达式：匹配"键: [±]? 数值"格式
        Pattern pattern = Pattern.compile("^(.*?):\\s*([+-]?)\\s*(\\d+)$");

        for (String stat : stats) {
            Matcher matcher = pattern.matcher(stat);
            if (matcher.matches()) {
                String key = matcher.group(1).trim();
                String symbol = matcher.group(2).trim();
                int value = Integer.parseInt(matcher.group(3).trim());

                // 如果是首次出现该属性，记录符号格式
                if (!symbolMap.containsKey(key)) {
                    // 统一处理符号，首次无符号默认为正号
                    symbolMap.put(key, symbol.isEmpty() ? "+" : symbol);
                }

                // 计算数值（如果符号为负则取负值）
                int actualValue = symbol.isEmpty() || "+".equals(symbol) ? value : -value;
                // 累加数值
                valueMap.put(key, valueMap.getOrDefault(key, 0) + actualValue);
            }
        }

        // 构建结果列表
        List<String> result = new ArrayList<>();
        for (Map.Entry<String, Integer> entry : valueMap.entrySet()) {
            String key = entry.getKey();
            int total = entry.getValue();
            String symbol = symbolMap.get(key);

            // 拼接结果字符串，保持首次出现的符号格式
            result.add(String.format("%s: %s %d", key, symbol, total));
        }

        return result;
    }

    /**
     * 对PlayerSortData集合排序，返回LinkedList
     * 排序规则：
     * 1. number降序（数值越大越靠前）
     * 2. 若number相同，按updateDateTime降序（时间越晚越靠前）
     * @param sourceList 原始对象集合
     * @return 排序后的LinkedList
     */
    public static LinkedList<PlayerSortData> sortPlayerData(List<PlayerSortData> sourceList) {
        if (sourceList == null || sourceList.isEmpty()) {
            return new LinkedList<>();
        }

        // 构建比较器
        Comparator<PlayerSortData> comparator = (data1, data2) -> {
            // 1. 先按number降序比较
            int numberCompare = compareNumber(data1.getNumber(), data2.getNumber());
            if (numberCompare != 0) {
                return numberCompare;
            }

            // 2. number相同则按updateDateTime降序比较
            return compareDateTime(data1.getUpdateDateTime(), data2.getUpdateDateTime());
        };

        // 排序并转换为LinkedList
        return sourceList.stream()
                .sorted(comparator)
                .collect(Collectors.toCollection(LinkedList::new));
    }

    /**
     * 比较两个Number（降序）
     * 处理null：null视为最小值，排在最后
     */
    private static int compareNumber(Number num1, Number num2) {
        if (num1 == null && num2 == null) {
            return 0;
        }
        if (num1 == null) {
            return 1; // num1为null，排在num2后面
        }
        if (num2 == null) {
            return -1; // num2为null，排在num1后面
        }

        // 数值降序（num1大则靠前）
        double value1 = num1.doubleValue();
        double value2 = num2.doubleValue();
        return Double.compare(value2, value1); // 交换顺序实现降序
    }

    /**
     * 比较两个时间字符串（固定格式yyyy-MM-dd HH:mm:ss，降序）
     * 处理异常：解析失败的时间视为最早时间，排在最后
     */
    private static int compareDateTime(String time1, String time2) {
        LocalDateTime dt1 = parseDateTime(time1);
        LocalDateTime dt2 = parseDateTime(time2);

        if (dt1 == null && dt2 == null) {
            return 0;
        }
        if (dt1 == null) {
            return 1; // time1解析失败，排在后面
        }
        if (dt2 == null) {
            return -1; // time2解析失败，排在后面
        }

        // 时间降序（dt1晚则靠前）
        return dt2.compareTo(dt1); // 交换顺序实现降序
    }

    /**
     * 解析固定格式的时间字符串（yyyy-MM-dd HH:mm:ss）
     * @param timeStr 时间字符串
     * @return 解析后的LocalDateTime，失败则返回null
     */
    private static LocalDateTime parseDateTime(String timeStr) {
        if (timeStr == null || timeStr.trim().isEmpty()) {
            return null;
        }
        try {
            return LocalDateTime.parse(timeStr.trim(), StaticSystemVarConst.DATE_FORMATTER);
        } catch (Exception e) {
            // 格式不符合时返回null（视为无效时间）
            return null;
        }
    }

    /**
     * 根据对象的ranking字段升序排序并转换为LinkedList
     * @param list 原始对象集合
     * @return 升序排序后的LinkedList
     */
    public static LinkedList<PlayerData> sortByRankingAsc(List<PlayerData> list) {
        if (list == null || list.isEmpty()) {
            return new LinkedList<>();
        }

        // 使用Stream排序：
        // 1. 提取ranking字段进行比较
        // 2. 按升序排列（自然顺序）
        // 3. 收集为LinkedList
        return list.stream()
                .sorted(Comparator.comparingInt(PlayerData::getRanking)) // 按ranking升序
                .collect(Collectors.toCollection(LinkedList::new));
    }

    /**
     * 集合按照指定个数分一组，返回List类型集合
     * @param originalList 原集合
     * @return 返回集合
     */
    public static <T> List<List<T>> splitList(List<T> originalList, Integer count) {
        List<List<T>> splitList = new ArrayList<>();
        int size = originalList.size();
        if(count > size) count = size;
        for (int i = 0; i < size; i += count) {
            int toIndex = Math.min(i + count, size);
            List<T> subList = originalList.subList(i, toIndex);
            splitList.add(subList);
        }
        return splitList;
    }

    /**
     * 按照指定正则 取出字符串中包含该格式的所有元素返回集合
     * <> <[^>]+>
     * @param input
     * @return
     */
    public static List<String> extractExpressions(String input, String regex) {
        List<String> result = new ArrayList<>();
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(input);
        // 查找所有匹配的内容
        while (matcher.find()) {
            result.add(matcher.group());
        }
        return result;
    }

    public static <T> Boolean isNotBlank(List<T> list) {
        return null != list && list.size() != 0;
    }

    public static <T> Boolean isBlank(List<T> list) {
        return !isNotBlank(list);
    }

    public static <T> String formatString(List<T> list, String splitSymbol) {
        StringBuilder finalStr = new StringBuilder();
        for (int i = 0; i < list.size(); i++) {
            finalStr.append(list.get(i).toString());
            if(i != list.size() - 1) {
                finalStr.append(splitSymbol);
            }
        }
        return finalStr.toString();
    }

    public static List<Integer> parseRange(String rangeStr) throws NumberFormatException{
        List<Integer> numbers = new ArrayList<>();

        // 分割字符串获取起始和结束数字
        String[] parts = rangeStr.split("-");
        if (parts.length != 2) {
            // 如果格式不正确，那么则没有分割
            numbers.add(Integer.parseInt(rangeStr.trim()));
            return numbers;
        }

            int start = Integer.parseInt(parts[0].trim());
            int end = Integer.parseInt(parts[1].trim());

            // 确保起始值小于等于结束值
            if (start > end) {
                int temp = start;
                start = end;
                end = temp;
            }

            // 添加范围内的所有整数
            for (int i = start; i <= end; i++) {
                numbers.add(i);
            }

        return numbers;
    }

}
